<template>
  <div class="min-h-screen py-8 px-4 sm:px-6 lg:px-8">
    <div class="max-w-4xl mx-auto">
      <!-- 页面标题 -->
      <div class="text-center mb-12">
        <h1 class="text-4xl font-bold mb-4 tech-text">Gamepad API</h1>
        <p class="text-gray-300 text-lg">
          连接和使用游戏手柄，访问按钮和摇杆状态
        </p>
      </div>

      <!-- 浏览器支持提示 -->
      <div v-if="!isSupported" class="tech-card mb-8 border-yellow-600">
        <div class="flex items-center mb-4">
          <i class="i-carbon-warning text-yellow-500 text-xl mr-3"></i>
          <h3 class="text-xl font-semibold text-yellow-500">浏览器支持提示</h3>
        </div>
        <p class="text-gray-300 mb-4">
          您的浏览器不支持 Gamepad API。此功能需要 Chrome 21+, Firefox 29+, Safari 10.1+ 或其他现代浏览器。
        </p>
        <p class="text-gray-400 text-sm">
          注意：需要连接游戏手柄并按下任意按钮才能检测到设备。
        </p>
      </div>

      <!-- 手柄连接状态 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">手柄连接状态</h2>
        
        <div class="bg-gray-800 rounded-lg p-6">
          <div class="flex items-center justify-between mb-6">
            <div class="flex items-center">
              <i :class="connectedGamepads.length > 0 ? 'i-carbon-game-console text-green-400' : 'i-carbon-game-console text-gray-400'" class="text-3xl mr-4"></i>
              <div>
                <h3 class="text-lg font-semibold text-white">
                  {{ connectedGamepads.length > 0 ? `已连接 ${connectedGamepads.length} 个手柄` : '未检测到手柄' }}
                </h3>
                <p class="text-gray-400 text-sm">
                  {{ connectedGamepads.length > 0 ? '手柄已就绪' : '请连接手柄并按下任意按钮' }}
                </p>
              </div>
            </div>
            <button
              @click="scanGamepads"
              :disabled="!isSupported"
              class="tech-button disabled:opacity-50 disabled:cursor-not-allowed"
            >
              <i class="i-carbon-renew mr-2"></i>
              扫描手柄
            </button>
          </div>

          <div v-if="connectedGamepads.length === 0" class="text-center py-8 text-gray-400">
            <i class="i-carbon-gamepad text-4xl mb-4 block mx-auto opacity-50"></i>
            <p>请连接游戏手柄并按下任意按钮</p>
            <p class="text-sm mt-2">支持 Xbox、PlayStation、Switch Pro 等标准手柄</p>
          </div>
        </div>
      </div>

      <!-- 手柄列表 -->
      <div v-if="connectedGamepads.length > 0" class="space-y-6">
        <div
          v-for="gamepad in connectedGamepads"
          :key="gamepad.index"
          class="tech-card"
        >
          <div class="flex items-center justify-between mb-6">
            <div>
              <h3 class="text-xl font-semibold text-white">{{ gamepad.id }}</h3>
              <p class="text-gray-400 text-sm">手柄 #{{ gamepad.index + 1 }}</p>
            </div>
            <div class="flex gap-2">
              <span class="px-3 py-1 bg-green-600 text-white rounded-full text-sm">
                已连接
              </span>
            </div>
          </div>

          <!-- 按钮状态 -->
          <div class="mb-6">
            <h4 class="text-lg font-semibold text-white mb-4">按钮状态</h4>
            <div class="grid grid-cols-4 md:grid-cols-8 gap-3">
              <div
                v-for="(button, index) in gamepad.buttons"
                :key="index"
                class="bg-gray-800 rounded-lg p-3 text-center transition-all duration-150"
                :class="button.pressed ? 'bg-tech-accent scale-110' : ''"
              >
                <div class="text-white font-semibold mb-1">{{ getButtonName(index) }}</div>
                <div class="text-xs text-gray-400">
                  {{ Math.round(button.value * 100) }}%
                </div>
              </div>
            </div>
          </div>

          <!-- 摇杆状态 -->
          <div class="mb-6">
            <h4 class="text-lg font-semibold text-white mb-4">摇杆状态</h4>
            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
              <!-- 左摇杆 -->
              <div class="bg-gray-800 rounded-lg p-6">
                <h5 class="text-white font-medium mb-4 text-center">左摇杆</h5>
                <div class="relative w-48 h-48 mx-auto bg-gray-900 rounded-full">
                  <!-- 十字线 -->
                  <div class="absolute inset-0 flex items-center justify-center">
                    <div class="w-full h-px bg-gray-700"></div>
                  </div>
                  <div class="absolute inset-0 flex items-center justify-center">
                    <div class="w-px h-full bg-gray-700"></div>
                  </div>
                  <!-- 摇杆位置指示器 -->
                  <div
                    class="absolute w-8 h-8 bg-tech-accent rounded-full transform -translate-x-1/2 -translate-y-1/2 transition-all duration-100"
                    :style="{
                      left: `${50 + (gamepad.axes[0] || 0) * 40}%`,
                      top: `${50 + (gamepad.axes[1] || 0) * 40}%`
                    }"
                  ></div>
                </div>
                <div class="text-center mt-4 text-sm text-gray-400">
                  X: {{ (gamepad.axes[0] || 0).toFixed(2) }} | Y: {{ (gamepad.axes[1] || 0).toFixed(2) }}
                </div>
              </div>

              <!-- 右摇杆 -->
              <div class="bg-gray-800 rounded-lg p-6">
                <h5 class="text-white font-medium mb-4 text-center">右摇杆</h5>
                <div class="relative w-48 h-48 mx-auto bg-gray-900 rounded-full">
                  <!-- 十字线 -->
                  <div class="absolute inset-0 flex items-center justify-center">
                    <div class="w-full h-px bg-gray-700"></div>
                  </div>
                  <div class="absolute inset-0 flex items-center justify-center">
                    <div class="w-px h-full bg-gray-700"></div>
                  </div>
                  <!-- 摇杆位置指示器 -->
                  <div
                    class="absolute w-8 h-8 bg-green-400 rounded-full transform -translate-x-1/2 -translate-y-1/2 transition-all duration-100"
                    :style="{
                      left: `${50 + (gamepad.axes[2] || 0) * 40}%`,
                      top: `${50 + (gamepad.axes[3] || 0) * 40}%`
                    }"
                  ></div>
                </div>
                <div class="text-center mt-4 text-sm text-gray-400">
                  X: {{ (gamepad.axes[2] || 0).toFixed(2) }} | Y: {{ (gamepad.axes[3] || 0).toFixed(2) }}
                </div>
              </div>
            </div>
          </div>

          <!-- 手柄详细信息 -->
          <div class="bg-gray-800 rounded-lg p-4">
            <h5 class="text-white font-medium mb-3">详细信息</h5>
            <div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
              <div>
                <div class="text-gray-400">索引</div>
                <div class="text-white font-semibold">{{ gamepad.index }}</div>
              </div>
              <div>
                <div class="text-gray-400">按钮数量</div>
                <div class="text-white font-semibold">{{ gamepad.buttons.length }}</div>
              </div>
              <div>
                <div class="text-gray-400">摇杆数量</div>
                <div class="text-white font-semibold">{{ gamepad.axes.length }}</div>
              </div>
              <div>
                <div class="text-gray-400">时间戳</div>
                <div class="text-white font-semibold">{{ Math.round(gamepad.timestamp) }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 测试游戏 -->
      <div v-if="connectedGamepads.length > 0" class="tech-card mb-8">
        <h3 class="text-xl font-semibold mb-6 text-white">手柄测试游戏</h3>
        
        <div class="bg-gray-800 rounded-lg p-6">
          <div class="relative w-full h-64 bg-gray-900 rounded-lg overflow-hidden mb-4">
            <!-- 玩家方块 -->
            <div
              class="absolute w-8 h-8 bg-tech-accent rounded transition-all duration-100"
              :style="{
                left: `${playerX}px`,
                top: `${playerY}px`
              }"
            ></div>
            
            <!-- 得分 -->
            <div class="absolute top-4 left-4 text-white text-xl font-bold">
              得分: {{ score }}
            </div>
          </div>
          
          <div class="text-center text-gray-300 text-sm">
            使用左摇杆或方向键移动蓝色方块
          </div>
        </div>
      </div>

      <!-- 振动测试 -->
      <div v-if="connectedGamepads.length > 0 && supportsVibration" class="tech-card mb-8">
        <h3 class="text-xl font-semibold mb-6 text-white">振动测试</h3>
        
        <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
          <button
            @click="testVibration('weak')"
            class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-4 rounded-lg transition-colors"
          >
            <i class="i-carbon-notification mr-2"></i>
            轻微振动
          </button>
          <button
            @click="testVibration('medium')"
            class="bg-orange-600 hover:bg-orange-700 text-white px-6 py-4 rounded-lg transition-colors"
          >
            <i class="i-carbon-notification-filled mr-2"></i>
            中等振动
          </button>
          <button
            @click="testVibration('strong')"
            class="bg-red-600 hover:bg-red-700 text-white px-6 py-4 rounded-lg transition-colors"
          >
            <i class="i-carbon-warning mr-2"></i>
            强烈振动
          </button>
        </div>
      </div>

      <!-- 事件日志 -->
      <div v-if="eventLogs.length > 0" class="tech-card mb-8">
        <h3 class="text-xl font-semibold mb-4 text-white">事件日志</h3>
        
        <div class="space-y-2 max-h-64 overflow-y-auto">
          <div
            v-for="(log, index) in eventLogs.slice().reverse()"
            :key="index"
            class="bg-gray-800 rounded-lg p-3 text-sm"
          >
            <div class="flex justify-between items-center">
              <span :class="log.type === 'connected' ? 'text-green-400' : 'text-red-400'" class="font-medium">
                {{ log.event }}
              </span>
              <span class="text-gray-400">{{ formatTimestamp(log.timestamp) }}</span>
            </div>
            <p class="text-gray-300 text-xs mt-1">{{ log.details }}</p>
          </div>
        </div>
        
        <div class="mt-4 pt-4 border-t border-gray-700">
          <button
            @click="clearEventLogs"
            class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg transition-colors text-sm"
          >
            <i class="i-carbon-trash-can mr-1"></i>
            清空日志
          </button>
        </div>
      </div>

      <!-- API 信息 -->
      <div class="tech-card">
        <h3 class="text-xl font-semibold mb-4 text-white">API 信息</h3>
        <div class="space-y-4 text-gray-300">
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">浏览器支持</h4>
            <p>Chrome 21+, Firefox 29+, Safari 10.1+, Edge 12+</p>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">主要方法</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">navigator.getGamepads()</code> - 获取所有手柄</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">gamepad.buttons</code> - 获取按钮状态</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">gamepad.axes</code> - 获取摇杆状态</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">gamepad.vibrationActuator</code> - 控制振动</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">事件监听</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">gamepadconnected</code> - 手柄连接</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">gamepaddisconnected</code> - 手柄断开</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">使用场景</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>浏览器游戏开发</li>
              <li>虚拟现实应用</li>
              <li>模拟器和仿真器</li>
              <li>多媒体控制应用</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">标准布局</h4>
            <p class="text-sm">标准手柄通常有17个按钮：</p>
            <ul class="list-disc list-inside space-y-1 text-sm mt-2">
              <li>0-3: 面部按钮 (A/B/X/Y 或 ×/○/□/△)</li>
              <li>4-5: 肩部按钮 (L1/R1 或 LB/RB)</li>
              <li>6-7: 扳机按钮 (L2/R2 或 LT/RT)</li>
              <li>8-9: 选择/开始按钮</li>
              <li>10-11: 摇杆按下 (L3/R3)</li>
              <li>12-15: 方向键 (上/下/左/右)</li>
              <li>16: 主页按钮</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'

// 类型定义
interface GamepadState {
  index: number
  id: string
  buttons: GamepadButton[]
  axes: number[]
  timestamp: number
}

interface EventLog {
  event: string
  details: string
  type: 'connected' | 'disconnected'
  timestamp: number
}

// 响应式状态
const isSupported = ref(false)
const connectedGamepads = ref<GamepadState[]>([])
const supportsVibration = ref(false)
const eventLogs = ref<EventLog[]>([])

// 游戏状态
const playerX = ref(200)
const playerY = ref(100)
const score = ref(0)

let animationFrameId: number | null = null

// 按钮名称映射
const buttonNames: Record<number, string> = {
  0: 'A/×',
  1: 'B/○',
  2: 'X/□',
  3: 'Y/△',
  4: 'LB',
  5: 'RB',
  6: 'LT',
  7: 'RT',
  8: 'Select',
  9: 'Start',
  10: 'L3',
  11: 'R3',
  12: '↑',
  13: '↓',
  14: '←',
  15: '→',
  16: 'Home'
}

// 初始化
onMounted(() => {
  checkSupport()
  addEventListeners()
  startGameLoop()
})

// 清理
onUnmounted(() => {
  removeEventListeners()
  stopGameLoop()
})

// 检查浏览器支持
const checkSupport = () => {
  isSupported.value = 'getGamepads' in navigator
  scanGamepads()
}

// 添加事件监听器
const addEventListeners = () => {
  window.addEventListener('gamepadconnected', handleGamepadConnected)
  window.addEventListener('gamepaddisconnected', handleGamepadDisconnected)
}

// 移除事件监听器
const removeEventListeners = () => {
  window.removeEventListener('gamepadconnected', handleGamepadConnected)
  window.removeEventListener('gamepaddisconnected', handleGamepadDisconnected)
}

// 处理手柄连接
const handleGamepadConnected = (e: GamepadEvent) => {
  addEventLog('手柄已连接', `${e.gamepad.id} (索引: ${e.gamepad.index})`, 'connected')
  scanGamepads()
}

// 处理手柄断开
const handleGamepadDisconnected = (e: GamepadEvent) => {
  addEventLog('手柄已断开', `${e.gamepad.id} (索引: ${e.gamepad.index})`, 'disconnected')
  scanGamepads()
}

// 扫描手柄
const scanGamepads = () => {
  if (!isSupported.value) return
  
  const gamepads = navigator.getGamepads()
  const connected: GamepadState[] = []
  
  for (const gamepad of gamepads) {
    if (gamepad) {
      connected.push({
        index: gamepad.index,
        id: gamepad.id,
        buttons: Array.from(gamepad.buttons),
        axes: Array.from(gamepad.axes),
        timestamp: gamepad.timestamp
      })
      
      // 检查是否支持振动
      if ((gamepad as any).vibrationActuator) {
        supportsVibration.value = true
      }
    }
  }
  
  connectedGamepads.value = connected
}

// 开始游戏循环
const startGameLoop = () => {
  const gameLoop = () => {
    updateGame()
    animationFrameId = requestAnimationFrame(gameLoop)
  }
  gameLoop()
}

// 停止游戏循环
const stopGameLoop = () => {
  if (animationFrameId) {
    cancelAnimationFrame(animationFrameId)
  }
}

// 更新游戏
const updateGame = () => {
  scanGamepads()
  
  if (connectedGamepads.value.length > 0) {
    const gamepad = connectedGamepads.value[0]
    
    // 使用左摇杆或方向键移动
    const speed = 5
    const axisX = gamepad.axes[0] || 0
    const axisY = gamepad.axes[1] || 0
    
    // 应用死区
    const deadzone = 0.1
    if (Math.abs(axisX) > deadzone) {
      playerX.value = Math.max(0, Math.min(600 - 32, playerX.value + axisX * speed))
    }
    if (Math.abs(axisY) > deadzone) {
      playerY.value = Math.max(0, Math.min(256 - 32, playerY.value + axisY * speed))
    }
    
    // 方向键
    if (gamepad.buttons[14]?.pressed) playerX.value = Math.max(0, playerX.value - speed)
    if (gamepad.buttons[15]?.pressed) playerX.value = Math.min(600 - 32, playerX.value + speed)
    if (gamepad.buttons[12]?.pressed) playerY.value = Math.max(0, playerY.value - speed)
    if (gamepad.buttons[13]?.pressed) playerY.value = Math.min(256 - 32, playerY.value + speed)
    
    // 按A按钮增加分数
    if (gamepad.buttons[0]?.pressed) {
      score.value++
    }
  }
}

// 测试振动
const testVibration = async (intensity: 'weak' | 'medium' | 'strong') => {
  const gamepads = navigator.getGamepads()
  
  for (const gamepad of gamepads) {
    if (gamepad && (gamepad as any).vibrationActuator) {
      const intensityMap = {
        weak: 0.3,
        medium: 0.6,
        strong: 1.0
      }
      
      try {
        await (gamepad as any).vibrationActuator.playEffect('dual-rumble', {
          startDelay: 0,
          duration: 200,
          weakMagnitude: intensityMap[intensity],
          strongMagnitude: intensityMap[intensity]
        })
      } catch (err) {
        console.error('振动失败:', err)
      }
    }
  }
}

// 获取按钮名称
const getButtonName = (index: number): string => {
  return buttonNames[index] || `B${index}`
}

// 添加事件日志
const addEventLog = (event: string, details: string, type: 'connected' | 'disconnected') => {
  eventLogs.value.push({
    event,
    details,
    type,
    timestamp: Date.now()
  })
  
  // 只保留最近20条记录
  if (eventLogs.value.length > 20) {
    eventLogs.value.splice(0, eventLogs.value.length - 20)
  }
}

// 清空事件日志
const clearEventLogs = () => {
  eventLogs.value = []
}

// 格式化时间戳
const formatTimestamp = (timestamp: number): string => {
  return new Date(timestamp).toLocaleTimeString('zh-CN')
}
</script>
